New Uses For FSAVE
roy g biv / defjam
New Uses For FSAVE roy g biv / defjam -= defjam =- since 1992 bringing you the viruses of tomorrow today! Former DOS/Win16 virus writer, author of several virus families, including Ginger (see Coderz #1 zine for terrible buggy example, contact me for better sources ;), and Virus Bulletin 9/95 for a description of what they called Rainbow. Co-author of world's first virus using circular partition trick (Orsam, coded with Prototype in 1993). Designer of world's first XMS swapping virus (John Galt, coded by RT Fishel in 1995, only 30 bytes stub, the rest is swapped out). Author of world's first virus using Thread Local Storage for replication (Shrug, see Virus Bulletin 6/02 for a description, but they call it Chiton), world's first virus using Visual Basic 5/6 language extensions for replication (OU812), world's first Native executable virus (Chthon), world's first virus using process co-operation to prevent termination (Gemini, see Virus Bulletin 9/02 for a description), world's first virus using polymorphic SMTP headers (JunkMail, see Virus Bulletin 11/02 for a description), world's first viruses that can convert any data files to infectable objects (Pretext), world's first 32/64-bit parasitic EPO .NET virus (Croissant, see Virus Bulletin 11/04 for a description, but they call it Impanate), world's first virus using self-executing HTML (JunkHTMaiL, see Virus Bulletin 7/03 for a description), world's first virus for Win64 on Intel Itanium (Shrug, see Virus Bulletin 6/04 for a description, but they call it Rugrat), world's first virus for Win64 on AMD AMD64 (Shrug), world's first cross-infecting virus for Intel IA32 and AMD AMD64 (Shrug), world's first viruses that infect Office applications and script files using the same code (Macaroni, see Virus Bulletin 11/05 for a description, but they call it Macar), world's first viruses that can infect both VBS and JScript using the same code (ACDC, see Virus Bulletin 11/05 for a description, but they call it Cada), world's first virus that can infect CHM files (Charm, see Virus Bulletin 10/06 for a description, but they call it Chamb), world's first IDA plugin virus (Hidan, see Virus Bulletin 3/07 for a description), world's first viruses that use the Microsoft Script Encoder to dynamically encrypt the virus body (Screed), world's first virus for StarOffice and OpenOffice (Starbucks), world's first virus IDC virus (ID10TiC), world's first polymorphic virus for Win64 on AMD AMD64 (Boundary, see Virus Bulletin 12/06 for a description, but they call it Bounds), world's first virus that can infect Intel-format and PowerPC-format Mach-O files (MachoMan, see Virus Bulletin 01/07 for a description, but they call it Macarena), world's first virus that uses Unicode escapes to dynamically encrypt the virus body, world's first self-executing PIF (Spiffy), world's first self-executing LNK (WeakLNK), and world's first virus that uses virtual code (Relock). Author of various retrovirus articles (eg see Vlad #7 for the strings that make your code invisible to TBScan). This is my fifteenth virus for Win32. It is the world's first virus to use FSAVE for instruction reordering. It is sad that this intro is longer than the text. What is FSAVE? FSAVE is an old instruction for the FPU which it seems has not been explored fully. Let us start by seeing what it does. When FSAVE is executed, it will store the state of the FPU to the specified memory location. The format of the state is known. It looks like this: Offset Size Name Value 0x00 0x02 Control variable 0x02 0x02 Filler 0xffff 0x04 0x02 Status 0x0000 0x06 0x02 Filler 0xffff 0x08 0x02 Tag 0x0000 because we fill all registers 0x0a 0x02 Filler 0xffff 0x0c 0x04 LastEip variable 0x10 0x02 LastCS variable 0x12 0x02 Opcode variable (instruction & 0x03ff) 0x14 0x04 LastData variable 0x18 0x02 LastDS variable 0x1a 0x02 Filler 0xffff 0x1c 0x0a st(0) user-defined 0x26 0x0a st(1) user-defined 0x30 0x0a st(2) user-defined 0x3a 0x0a st(3) user-defined 0x44 0x0a st(4) user-defined 0x4e 0x0a st(5) user-defined 0x58 0x0a st(6) user-defined 0x62 0x0a st(7) user-defined Since the st() array is at the end and we can control it completely, I got the idea to put instructions into it. Then if I use FSAVE at eip-0x21, so st(0) will be the next instruction to execute. It also means that I can write 0x50 bytes of code to memory using one instruction! One problem is that FPU cannot perform operations on arbitrary values loaded into the registers, because some of the values are considered "special", some are "NaNs", etc. However, we can load instructions from different places in memory and use the FPU to order them for us. We must remember that the values must be loaded in a reversed order, because the st() array is a stack, but there are no restriction about the address of the values. It is a nice coincidence that this sequence is exactly 0x21 bytes long, if byte offsets are used for the memory loads. It means that there is no risk that eax-0x21 will fall off the page and cause a fault. load: pop eax ;can be any register fld tbyte ptr [eax + x7] ;becomes st(7) fld tbyte ptr [eax + x6] ;becomes st(6) fld tbyte ptr [eax + x5] ;becomes st(5) fld tbyte ptr [eax + x4] ;becomes st(4) fld tbyte ptr [eax + x3] ;becomes st(3) fld tbyte ptr [eax + x2] ;becomes st(2) fld tbyte ptr [eax + x1] ;becomes st(1) fld tbyte ptr [eax + x0] ;becomes st(0) fnsave byte ptr [eax - 21] ;overwrite call with st(0) start: call load [here can be values to load into st() array] A 0x50 bytes array might not sound very large, but it is big enough for a RC4 decryptor, and almost big enough for XTEA, so we can put a nice decryptor in there. Since many AV emulators do not support FPU properly, it doesn't even need to be very complex if they can't run it. So FPU for reordering is interesting, but it is limited because we cannot use arithmetic operations. We can avoid that problem, but it must wait for next time. :) Greets to friendly people (A-Z): Active - Benny - izee - Malum - Obleak - Prototype - Ratter - Ronin - RT Fishel - sars - SPTH - The Gingerbread Man - Ultras - uNdErX - Vallez - Vecna - VirusBuster - Whitehead rgb/defjam nov 2007 iam_rgb@hotmail.com